package com.cxx.purchasecharge.service.impl;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import com.cxx.purchasecharge.core.model.CustomerTypeCode;
import com.cxx.purchasecharge.core.model.OrderSearchForm;
import com.cxx.purchasecharge.core.model.OrderTypeCode;
import com.cxx.purchasecharge.core.model.persistence.Contact;
import com.cxx.purchasecharge.core.model.persistence.Customer;
import com.cxx.purchasecharge.core.model.persistence.Goods;
import com.cxx.purchasecharge.core.model.persistence.GoodsType;
import com.cxx.purchasecharge.core.model.persistence.Order;
import com.cxx.purchasecharge.core.model.persistence.OrderItem;
import com.cxx.purchasecharge.dal.ContactDao;
import com.cxx.purchasecharge.dal.CustomerDao;
import com.cxx.purchasecharge.dal.GoodsDao;
import com.cxx.purchasecharge.dal.OrderDao;
import com.cxx.purchasecharge.dal.OrderItemDao;
import com.cxx.purchasecharge.dal.UserDao;
import com.cxx.purchasecharge.service.QueryService;

@Repository ("queryService")
public class QueryServiceImpl implements QueryService
{
    private static final Logger logger = Logger.getLogger (QueryServiceImpl.class);

    @Autowired
    private ContactDao contactDao;
    @Autowired
    private CustomerDao baseCustomerDao;
    @Autowired
    private OrderDao baseOrderDao;
    @Autowired
    private OrderItemDao orderItemDao;
    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private UserDao userDao;

    @Override
    public Contact getContact (long id)
    {
        return contactDao.findOne (id);
    }

    @Override
    public Contact getContact (String name)
    {
        return contactDao.findByName (name);
    }

    @Override
    public Page <Contact> findContactByFuzzy (Pageable pageable, String searchKey, String signUser, boolean admin)
    {
        return contactDao.findByFuzzy (pageable, searchKey, getUniqueIdByUserId(signUser), admin);
    }

    @Override
    public Customer getCustomer (long id)
    {
        return baseCustomerDao.findOne (id);
    }

    @Override
    public Customer getCustomer (String name)
    {
        return baseCustomerDao.findByShortName (name);
    }

    @Override
    public Customer getCustomerByContact (long contactId)
    {
        Contact contact = contactDao.findOne (contactId);
        if (null != contact)
        {
            return contact.getCustomer ();
        }
        return null;
    }

    @Override
    public List <Customer> getAllCustomer (CustomerTypeCode typeCode, String signUser, boolean admin)
    {
        return baseCustomerDao.findAllCustomer (typeCode, getUniqueIdByUserId(signUser), admin);
    }

    @Override
    public Page <Customer> findCustomerByFuzzy (Pageable pageable, String searchKey, String signUser, boolean admin)
    {
        return baseCustomerDao.findCustomerByFuzzy (pageable, searchKey, getUniqueIdByUserId(signUser), admin);
    }

    @Override
    public Page <Customer> findByFuzzy (CustomerTypeCode typeCode, Pageable pageable, String searchKey,
                                        String signUser, boolean admin)
    {
        return baseCustomerDao.findByFuzzy (typeCode, pageable, searchKey, getUniqueIdByUserId(signUser), admin);
    }

    @Override
    public float countCustomerUnpay (CustomerTypeCode typeCode, String searchKey, String signUser, boolean admin)
    {
        return baseCustomerDao.countUnpayBy (typeCode, searchKey, getUniqueIdByUserId(signUser), admin);
    }

    @Override
    public Order findOrderById (long id)
    {
        return baseOrderDao.findOne (id);
    }

    @Override
    public List <OrderItem> findOrderItemByOrder (Order order)
    {
        if (null == order)
        {
            logger.warn ("Order must be not null.");
        }
        if (order.getId () == 0)
        {
            logger.warn ("Order id must be not equal to 0.");
        }
        if (null != order && order.getId () != 0)
        {
            return orderItemDao.findByOrder (order);
        }
        return null;
    }

    @Override
    public List<OrderItem> findOrderItemWithOrder(long orderId)
    {
        return orderItemDao.findByOrder (orderId);
    }

    @Override
    public Page <Order> findOrderByFuzzy (OrderTypeCode typeCode, Pageable pageable, String searchKey, String signUser,
                                          boolean admin)
    {
        return baseOrderDao.findByFuzzy (typeCode, pageable, searchKey, getUniqueIdByUserId(signUser), admin);
    }

    @Override
    public Page <Order> findOrderBySearchForm (OrderTypeCode typeCode, Pageable pageable, OrderSearchForm searchForm,
                                               String signUser, boolean admin)
    {
        return baseOrderDao.findBySearchForm (typeCode, pageable, searchForm, getUniqueIdByUserId(signUser), admin);
    }

    @Override
    public Page <Order> findOrderBySearchForm (boolean isOut, Pageable pageable, OrderSearchForm searchForm,
                                               String signUser, boolean admin)
    {
        return baseOrderDao.findBySearchForm (isOut, pageable, searchForm, getUniqueIdByUserId(signUser), admin);
    }

    @Override
    public float countOrderReceivableBySearchForm (OrderTypeCode typeCode,
                                                   OrderSearchForm searchForm, String signUser, boolean admin)
    {
        return baseOrderDao.countReceivableBy (typeCode, searchForm, getUniqueIdByUserId(signUser), admin);
    }

    @Override
    public float countOrderProfitBySearchForm (OrderTypeCode typeCode, OrderSearchForm searchForm,
                                               String signUser, boolean admin)
    {
        return baseOrderDao.countProfitBy (typeCode, searchForm, getUniqueIdByUserId(signUser), admin);
    }

    @Override
    public List <Order> getOrderByCustomer (long customerId)
    {
        return baseOrderDao.findByCustomerId (customerId);
    }

    @Override
    public List <OrderItem> getOrderItemByOrder (Order order)
    {
        return orderItemDao.findByOrder (order);
    }

    @Override
    public List <OrderItem> getOrderItemByGoods (long goodsId)
    {
        return orderItemDao.findByGoods (goodsId);
    }

    @Override
    public Goods getGoods (String name)
    {
        return goodsDao.findByName (name);
    }

    @Override
    public List <Goods> getGoods (GoodsType type)
    {
        return goodsDao.findByType (type);
    }

    @Override
    public long getUniqueIdByUserId(String userId)
    {
        if(StringUtils.isNotBlank (userId)) 
        {
            return userDao.getUniqueIdByUserId(userId);
        }
        return 0;
    }

}
